package cn.zhangsw.generator.util;

import cn.hutool.core.date.DateTime;
import cn.zhangsw.generator.config.AutoCodeConfig;
import cn.zhangsw.generator.config.GlobalConfig;
import cn.zhangsw.generator.model.BeanColumn;
import cn.zhangsw.generator.model.TsysTables;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.*;
import java.util.*;

/**
 * 自动生成 通用类
 *
 * @author fuce
 * @ClassName: AutoCodeUtil
 * @date 2019-11-20 22:05
 */
public class AutoCodeUtil {

	private AutoCodeUtil() {
	}

	/**
	 * 生成文件路径
	 **/
	private static String targetPath = getTargetPath();


	public static String getTargetPath() {

		System.out.println("==================》》》》》》》》"+AutoCodeConfig.getGlobalConfig().getParentPath());
		return AutoCodeConfig.getGlobalConfig().getParentPath();
	}

	public static List<String> getTemplates() {
		List<String> templates = new ArrayList<String>();

		//java代码模板
		templates.add("auto_code/model/Entity.java.vm");
		templates.add("auto_code/model/EntityExample.java.vm");
		templates.add("auto_code/mapperxml/EntityMapper.xml.vm");
		templates.add("auto_code/service/EntityService.java.vm");
		templates.add("auto_code/dao/EntityMapper.java.vm");
		templates.add("auto_code/controller/EntityController.java.vm");
		return templates;
	}

	/**
	 * 创建单表
	 *
	 * @param conditionQueryField 条件查询字段
	 * @param vController         生成controller
	 * @param vservice            生成service
	 * @param vMapperORdao        生成mapper or dao
	 * @author fuce
	 * @Date 2019年8月24日 下午11:44:54
	 */
	public static void autoCodeOneModel(TsysTables tables,
										List<BeanColumn> beanColumns, String conditionQueryField,
										Boolean vController, Boolean vService, Boolean vMapperORdao) {

		//设置velocity资源加载器
		Properties prop = new Properties();
		prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		Velocity.init(prop);

		GlobalConfig globalConfig = AutoCodeConfig.getGlobalConfig();
		Map<String, Object> map = new HashMap<>();
		//数据库表数据
		map.put("TsysTables", tables);
		//字段集合
		map.put("beanColumns", beanColumns);
		//配置文件
		map.put("globalConfig", globalConfig);
		map.put("datetime", new DateTime());

		map.put("conditionQueryField", conditionQueryField);
		map.put("conditionQueryField_a", StringUtils.firstLowerCase(conditionQueryField));
		map.put("SnowflakeIdWorker", SnowflakeIdWorker.class);
		//需要导入的java类
		map.put("JavaClassPackages", getJavaClassPackage(beanColumns));
		VelocityContext context = new VelocityContext(map);

		//获取模板列表
		List<String> templates = getTemplates();
		if (vController != true) {
			templates.remove("auto_code/controller/EntityController.java.vm");
		}
		if (vService != true) {
			templates.remove("auto_code/service/EntityService.java.vm");
		}
		if (vMapperORdao != true) {
			templates.remove("auto_code/model/Entity.java.vm");
			templates.remove("auto_code/model/EntityExample.java.vm");
			templates.remove("auto_code/mapperxml/EntityMapper.xml.vm");
			templates.remove("auto_code/dao/EntityMapper.java.vm");
		}


		for (String template : templates) {
			try {

				String filepath = getCoverFileName(template, tables.getTableModel_a(), tables.getTableModel(), globalConfig.getParentPack());
				Template tpl = Velocity.getTemplate(template, "UTF-8");
				File file = new File(filepath);
				if (!file.getParentFile().exists())
					file.getParentFile().mkdirs();
				if (!file.exists())
					file.createNewFile();
				try (FileOutputStream outStream = new FileOutputStream(file);
					 OutputStreamWriter writer = new OutputStreamWriter(outStream, "UTF-8");
					 BufferedWriter sw = new BufferedWriter(writer)) {
					tpl.merge(context, sw);
					sw.flush();
					System.out.println("成功生成Java文件:" + filepath);
				}


			} catch (IOException e) {
				try {
					throw new Exception("渲染模板失败，表名：" + tables.getTableName() + "\n" + e.getMessage());
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		}
	}


	/**
	 * 获取覆盖路径
	 */
	public static String getCoverFileName(String template, String classname, String className, String packageName) {
		String packagePath = targetPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator;
		String resourcesPath = targetPath + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator;

		GlobalConfig globalConfig = AutoCodeConfig.getGlobalConfig();

		if (StringUtils.isNotEmpty(packageName)) {
			packagePath += packageName.replace(".", File.separator) + File.separator;
		}

		if (template.contains("Entity.java.vm")) {//model.java

			String beanPackageName = globalConfig.getBeanPackageName();
			String beanNameSuffix = globalConfig.getBeanNameSuffix();

			return packagePath + beanPackageName + File.separator + className +beanNameSuffix+ ".java";
		}
		if (template.contains("EntityExample.java.vm")) {//modelExample.java
			String beanPackageName = globalConfig.getBeanPackageName();
			String beanNameSuffix = globalConfig.getBeanNameSuffix();
			return packagePath + beanPackageName + File.separator + className + beanNameSuffix+"Example.java";
		}

		if (template.contains("EntityMapper.java.vm")) {//daomapper.java

			String daoNameSuffix = globalConfig.getDaoNameSuffix();
			String daoPackageName = globalConfig.getDaoPackageName();


			return packagePath + daoPackageName + File.separator + className + daoNameSuffix+".java";
		}
		if (template.contains("EntityMapper.xml.vm")) {//daomapper.xml



			String daoNameSuffix = globalConfig.getDaoNameSuffix();

			return resourcesPath + globalConfig.getXmlPath() + File.separator + className + daoNameSuffix+".xml";
		}

		if (template.contains("EntityService.java.vm")) {
			String serviceNameSuffix = globalConfig.getServiceNameSuffix();
			String servicePackageName = globalConfig.getServicePackageName();
			return packagePath + servicePackageName + File.separator + className + serviceNameSuffix+".java";
		}
		if (template.contains("EntityController.java.vm")) {
			String controllerNameSuffix = globalConfig.getControllerNameSuffix();
			String controllerPackageName = globalConfig.getControllerPackageName();


			return packagePath + controllerPackageName + File.separator + className + controllerNameSuffix+".java";
		}


		return null;
	}


	/**
	 * 获取javamodel需要的导入类
	 *
	 * @author fuce
	 * @Date 2019年8月26日 下午11:11:09
	 */
	public static String getJavaClassPackage(List<BeanColumn> beanColumns) {
		Map<String, String> map = new HashMap<>();
		StringBuffer buffer = new StringBuffer();
		for (BeanColumn beanColumn : beanColumns) {
			map.put(beanColumn.getBeanType(), beanColumn.getBeanType());
		}
		if (map.size() > 0) {
			boolean time = false;
			for (String key : map.keySet()) {
				if (!"java.lang.String".equals(key)) {
					buffer.append("import " + map.get(key) + ";\n");
				}
				if ("java.util.Date".equals(key) && time == false) {
					time = true;
					buffer.append("import com.fasterxml.jackson.annotation.JsonFormat;\n");
				}
			}
		}
		return buffer.toString();
	}

}
